#ifndef	__BFX_REF_XMLATTRIBUTEMAP_H__
#define	__BFX_REF_XMLATTRIBUTEMAP_H__

namespace BFX
{

//////////////////////////////////////////////////////////////////////////////

// Represents a map of attributes that can be accessed by name or index.
class BFX_API REFXMLAttributeMap : public REFXMLNodeMap
{
	friend class REFXMLElement;
	friend class REFXMLAttribute;

public:
	virtual ~REFXMLAttributeMap();

	// Gets the attribute with the specified index.
	REFXMLAttribute* GetAttribute(int iIndex) const;
	// Gets the attribute with the specified name.
	REFXMLAttribute* GetAttribute(const UniString& strName) const;
	// Gets the attribute with the specified LocalName and NamespaceUri.
	REFXMLAttribute* GetAttribute(const UniString& strLocalName, const UniString& strNamespaceURI) const;

	// Inserts the specified node as the first node in the collection.
	REFXMLAttribute* Prepend(REFXMLAttribute* pNode);
	// Inserts the specified node as the last node in the collection.
	REFXMLAttribute* Append(REFXMLAttribute* pNode);
	// Inserts the specified attribute immediately before the specified reference attribute.
	REFXMLAttribute* InsertBefore(REFXMLAttribute* pNewNode, REFXMLAttribute* pRefNode);
	// Inserts the specified attribute immediately after the specified reference attribute.
	REFXMLAttribute* InsertAfter(REFXMLAttribute* pNewNode, REFXMLAttribute* pRefNode);

	// Removes the specified attribute node from the map.
	REFXMLAttribute* Remove(REFXMLAttribute* pNode);
	// Removes the attribute node with the specified index from the map.
	REFXMLAttribute* RemoveAt(int i);
	// Removes all attributes from the map.
	void RemoveAll();

	virtual REFXMLNode* SetNamedItem(REFXMLNode* pNode);

protected:
	REFXMLAttributeMap(REFXMLNode* pParent);

	void Detach(REFXMLAttribute* pAttr);
	// the function checks if there is already node with the same name existing in the collection
	// if so, remove it because the new one will be inserted to replace this one (could be in different position though ) 
	// by the calling function later
	int RemoveDuplicateAttribute(REFXMLAttribute* pAttr);
	// WARNING: 
	//  For performance reasons, this function does not check
	//  for xml attributes within the collection with the same full name.
	//  This means that any caller of this function must be sure that
	//  a duplicate attribute does not exist.
	REFXMLAttribute* AppendAttribute(REFXMLAttribute* pNode);

	// insert the parent element node into the map
	void InsertParentIntoElementIdAttrMap(REFXMLAttribute* pAttr);
	//remove the parent element node from the map when the ID attribute is removed
	void RemoveParentFromElementIdAttrMap(REFXMLAttribute* pAttr);

	bool PrepareParentInElementIdAttrMap(const UniString& strAttrPrefix, const UniString& strAttrLocalName);
	void ResetParentInElementIdAttrMap(const UniString& strOldVal, const UniString& strNewVal);

	virtual REFXMLNode* AddNode(REFXMLNode* pNode);
	virtual REFXMLNode* InsertNodeAt(int i, REFXMLNode* pNode);
	virtual REFXMLNode* RemoveNodeAt(int i);
};

}	//	namespace BFX

#endif	//	__BFX_REF_XMLATTRIBUTEMAP_H__
